package cn.hwadee.muying.service;

import cn.hwadee.muying.commons.constant.ConstantJob;
import cn.hwadee.muying.commons.constant.ConstantRole;
import cn.hwadee.muying.commons.page.MyPage;
import cn.hwadee.muying.commons.utils.DateTools;
import cn.hwadee.muying.commons.utils.ExcelUtils;
import cn.hwadee.muying.commons.utils.Md5Utils;
import cn.hwadee.muying.dto.Worker;
import cn.hwadee.muying.entity.*;
import cn.hwadee.muying.enums.Education;
import cn.hwadee.muying.enums.Level;
import cn.hwadee.muying.excel.ConstantWorker;
import cn.hwadee.muying.mapper.ClientInfoMapper;
import cn.hwadee.muying.mapper.WorkerLevelMapper;
import cn.hwadee.muying.mapper.WorkerMapper;
import cn.hwadee.muying.mapper.PromotionLogMapper;
import com.baomidou.mybatisplus.enums.SqlMethod;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.*;

/**
 * Created by Mankind on 2018/8/7.
 */
@Service
public class WorkerService {

    @Autowired
    private UserService userService;

    @Autowired
    private WorkerInfoService workerInfoService;

    @Autowired
    private OrganizationService orgService;

    @Autowired
    private JobService jobService;

    @Autowired
    private SalaryService salaryService;

    @Autowired
    private CommentService commentService;

    protected final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WorkerMapper workerMapper;

    @Autowired
    private WorkerLevelMapper workerLevelMapper;

    @Autowired
    private PromotionLogMapper promotionLogMapper;

    public MyPage<Worker> list(MyPage<Worker> page, User cUser,Integer entryStatus, Long workerLevel, Long education,String keyword) throws Exception{
        page.setOrderByField("b.updateDate");
        List<Worker> workers = workerMapper.list(page,cUser,entryStatus,workerLevel,education,keyword);
        page.setRecords(workers);
        return page;
    }

    public MyPage<Worker> status(MyPage<Worker> page, User cUser,Long workerLevel, Long education,Integer free,String keyword) throws Exception{
        page.setOrderByField("b.updateDate");
        List<Worker> workers = workerMapper.status(page,cUser,workerLevel,education,free,keyword);
        page.setRecords(workers);
        return page;
    }

    public MyPage<Worker> frontList(MyPage<Worker> page,String city,String hometown,Long orgId,Long levelId,Long educationId,Integer startExperience,Integer endExperience,Integer startAge,Integer endAge,Integer startSalary,Integer endSalary) throws Exception{
        List<Worker> workers = workerMapper.frontList(page,city,hometown,orgId,levelId,educationId,startExperience,endExperience,startAge,endAge,startSalary,endSalary);
        for(Worker worker:workers){
            int level=worker.getWorkerLevel().getId();
            Salary salary=salaryService.selectByLevelId(level);
            if(salary!=null){
                worker.setStartSalary(salary.getStartSalary());
                worker.setPerSalary(salary.getPerSalary());
            }
        }
        page.setRecords(workers);
        return page;
    }


    public MyPage<Worker> care(MyPage<Worker> page, User cUser,String keyword) throws Exception{
        List<Worker> workers = workerMapper.care(cUser,keyword);
        for(Worker worker : workers){
            worker.setBirthdayString(DateTools.dayFormat.format(worker.getBirthday()));
            worker.setNextBirthdayDays(DateTools.nextBirthdayDays(worker.getBirthday()));
        }
        Collections.sort(workers);
        int size=page.getSize();
        int listSize=workers.size();
        page.setRecords(workers.subList(Math.min((page.getCurrent() - 1)* size,listSize), Math.min(page.getCurrent() * size,listSize)));
        page.setTotal(workers.size());
        return page;
    }

    public MyPage<Worker> upgrade(MyPage<Worker> page, User cUser,String keyword) throws Exception{
        List<Worker> workers = workerMapper.upgrade(cUser,keyword);
        for(Worker worker : workers){
            //Job job=jobService.selectById(worker.getJob());
           // System.out.println(worker.toString());
            worker.setJobName("育婴师");
            //System.out.println(worker.getHasNext());
            if(worker.getHasNext()){
                /*Long days = 0L;
                Date resentDate = promotionLogMapper.resentUpgrade(worker.getId(),worker.getOrgId());
                Timestamp resent;
                if(resentDate == null) resent = worker.getCreateDate();
                else resent = new Timestamp(resentDate.getTime());
                days = DateTools.betweetDays(resent,new Timestamp(System.currentTimeMillis()));*/
                worker.setNeedUpgradeMonths(Math.max(0L,worker.getNeededTime() - worker.getExperience()));
            }
        }
        Collections.sort(workers,new Comparator<Worker>() {
            @Override
            public int compare(Worker o1, Worker o2) {
                if(o1.getNeedUpgradeMonths()==null)return 1;
                if(o2.getNeedUpgradeMonths()==null)return -1;
                return o1.getNeedUpgradeMonths().compareTo(o2.getNeedUpgradeMonths());
            }
        });
        int size=page.getSize();
        int listSize=workers.size();
        page.setRecords(workers.subList(Math.min((page.getCurrent() - 1)* size,listSize), Math.min(page.getCurrent() * size,listSize)));
        page.setTotal(workers.size());
        return page;
    }

    public boolean insert(Worker worker,User cUser){
        try{
            User user=new User();
            user.setUsername(worker.getUsername());
            user.setAccount(worker.getAccount());
            user.setRid(worker.getRid());
            user.setOrgId(cUser.getOrgId());
            user.setPassword(new Md5Utils().getkeyBeanofStr(worker.getPassword()));
            user.setAddress(worker.getAddress());
            user.setBirthday(worker.getBirthday());
            user.setEmail(worker.getEmail());
            user.setTelephone(worker.getTelephone());
            userService.insert(user);

            //插入之后重新获取,得到主键id
            user=userService.getByAccount(user.getAccount());

            WorkerInfo workerInfo=new WorkerInfo();
            workerInfo.setUserId(user.getId());
            workerInfo.setImage(worker.getImage());
            workerInfo.setJob(worker.getJob());
            workerInfo.setNativePlace(worker.getNativePlace());
            workerInfo.setAge(worker.getAge());
            workerInfo.setConstellation(worker.getConstellation());
            workerInfo.setEducation(worker.getEducation());
            workerInfo.setExperience(worker.getExperience());
            workerInfo.setMarried(worker.getMarried());
            workerInfo.setEntryStatus(worker.getEntryStatus());
            workerInfo.setFree(true);
            workerInfo.setIntroduction(worker.getIntroduction());
            workerInfo.setWorkerLevel(worker.getWorkerLevel());
            workerInfo.setExpectedCity(worker.getExpectedCity());
            workerInfoService.insert(workerInfo);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }


    }



    public void updateById(Worker worker) throws RuntimeException {
        User user=userService.selectById(worker.getId());
        user.setUsername(worker.getUsername());
        user.setAccount(worker.getAccount());
        user.setRid(worker.getRid());
        user.setOrgId(worker.getOrgId());
        user.setAddress(worker.getAddress());
        user.setBirthday(worker.getBirthday());
        user.setEmail(worker.getEmail());
        user.setTelephone(worker.getTelephone());

        WorkerInfo workerInfo=workerInfoService.selectById(worker.getWorkerInfoId());
        workerInfo.setUserId(worker.getId());
        workerInfo.setImage(worker.getImage());
        workerInfo.setJob(worker.getJob());
        workerInfo.setNativePlace(worker.getNativePlace());
        workerInfo.setAge(worker.getAge());
        workerInfo.setConstellation(worker.getConstellation());
        workerInfo.setEducation(worker.getEducation());
        workerInfo.setExperience(worker.getExperience());
        workerInfo.setMarried(worker.getMarried());
        workerInfo.setEntryStatus(worker.getEntryStatus());
        workerInfo.setFree(worker.getFree());
        workerInfo.setIntroduction(worker.getIntroduction());
        workerInfo.setWorkerLevel(worker.getWorkerLevel());
        workerInfo.setExpectedCity(worker.getExpectedCity());
        userService.updateById(user);
        workerInfoService.updateById(workerInfo);
    }

//    public void delete(Worker worker) throws RuntimeException{
//        workerInfoService.deleteById(worker.getWorkerInfoId());
//        userService.deleteById(worker.getId());
//    }


    public Worker selectById(Long id) {
        User user=userService.selectById(id);
        WorkerInfo workerInfo=workerInfoService.selectByUserId(id);
        Salary salary=salaryService.selectByLevelId(workerInfo.getWorkerLevel().getId());
        List<Comment> comments=commentService.selectListByWorkerId(id);
        Long star=0L;
        if(comments.size()>0){
            for(Comment comment:comments){
                star+=comment.getStar();
            }
            star=star/comments.size();
        }
        Worker worker=new Worker();
        worker.setId(user.getId());
        worker.setAccount(user.getAccount());
        worker.setAddress(user.getAddress());
        worker.setAge(workerInfo.getAge());
        worker.setBirthday(user.getBirthday());
        worker.setConstellation(workerInfo.getConstellation());
        worker.setCreateDate(user.getCreateDate());
        worker.setDeleteDate(user.getDeleteDate());
        worker.setEducation(workerInfo.getEducation());
        worker.setEmail(user.getEmail());
        worker.setEntryStatus(workerInfo.getEntryStatus());
        worker.setExperience(workerInfo.getExperience());
        worker.setFree(workerInfo.getFree());
        worker.setImage(workerInfo.getImage());
        worker.setIntroduction(workerInfo.getIntroduction());
        worker.setJob(workerInfo.getJob());
        worker.setMarried(workerInfo.getMarried());
        worker.setNativePlace(workerInfo.getNativePlace());
        worker.setOrgId(user.getOrgId());
        worker.setPassword(user.getPassword());
        worker.setRid(user.getRid());
        worker.setTelephone(user.getTelephone());
        worker.setType(user.getType());
        worker.setUpdateDate(user.getUpdateDate());
        worker.setValid(user.getValid());
        worker.setUsername(user.getUsername());
        worker.setWorkerInfoId(workerInfo.getId());
        worker.setWorkerLevel(workerInfo.getWorkerLevel());
        worker.setExpectedCity(workerInfo.getExpectedCity());
        if(salary != null){
            worker.setStartSalary(salary.getStartSalary());
            worker.setPerSalary(salary.getPerSalary());
        }
        worker.setStar(star);
        return worker;
    }

    public void deleteById(Long id) {
        userService.deleteById(id);
        workerInfoService.deleteByUserId(id);
    }

    /**
     * 处理excel数据，生成worker列表，并插入数据库
     * @param
     * @return
     * @throws
     */

    public void insertWorkerByExcel(InputStream in, Long orgId) {
        List<Map> mapList = ExcelUtils.excelToMapList(
                in,
                ConstantWorker.importFieldMap,
                ConstantWorker.uniqueFields,
                ConstantWorker.notNullFields);
        List<Worker> workerList = ExcelUtils.mapListToWorkerList(mapList);
        Organization org=orgService.selectById(orgId);
        //获取机构内人数
        int num=userService.selectCount(
                new EntityWrapper<User>()
                        .and("org_id="+orgId)
                        .and("valid=1"));
        Md5Utils md5Utils=new Md5Utils();
        for(int i=0;i<workerList.size();i++){
            Worker worker=workerList.get(i);
            String account=worker.getTelephone();//用职员的手机号作为账号
            worker.setAccount(account);
            worker.setPassword(md5Utils.getkeyBeanofStr("123456"));//密码是123456
            worker.setOrgId(orgId);
            worker.setRid(ConstantRole.ROLE_NURSERY_TEACHER);//默认导入育婴师
            worker.setJob(ConstantJob.NURSERY_TEACHER);//默认导入育婴师
            worker.setEntryStatus(true);//入职状态为true
        }
        this.insertBatch(workerList);

    }

    /**
     * 用于EXCEL的批量插入
     * @param workerList
     * @return
     * @throws RuntimeException
     */
    private boolean insertBatch(List<Worker> workerList) throws RuntimeException {
        if (CollectionUtils.isEmpty(workerList)) {
            return false;
        }
        List<User> userList=new ArrayList<>();
        List<WorkerInfo> workerInfoList=new ArrayList<>();
        for(Worker worker:workerList){
            User user=new User();
            user.setUsername(worker.getUsername());
            user.setAccount(worker.getAccount());
            user.setRid(worker.getRid());
            user.setOrgId(worker.getOrgId());
            user.setPassword(worker.getPassword());
            user.setAddress(worker.getAddress());
            user.setBirthday(worker.getBirthday());
            user.setEmail(worker.getEmail());
            user.setTelephone(worker.getTelephone());
            userList.add(user);
        }
        userService.insertBatch(userList,50);

        for(Worker worker:workerList){
            //插入之后重新获取,得到主键id
            User user=userService.getByAccountAndTelephone(worker.getAccount(),worker.getTelephone());
            WorkerInfo workerInfo=new WorkerInfo();
            workerInfo.setUserId(user.getId());
            workerInfo.setImage(worker.getImage());
            workerInfo.setJob(worker.getJob());
            workerInfo.setNativePlace(worker.getNativePlace());
            workerInfo.setAge(worker.getAge());
            workerInfo.setConstellation(worker.getConstellation());
            workerInfo.setEducation(worker.getEducation());
            workerInfo.setExperience(worker.getExperience());
            workerInfo.setMarried(worker.getMarried());
            workerInfo.setEntryStatus(worker.getEntryStatus());
            workerInfo.setFree(true);
            workerInfo.setIntroduction(worker.getIntroduction());
            workerInfo.setWorkerLevel(worker.getWorkerLevel());
            workerInfo.setExpectedCity(worker.getExpectedCity());
            workerInfoList.add(workerInfo);
        }
        workerInfoService.insertBatch(workerInfoList,50);
        return true;
    }


    public void deleteBatchIds(List<Long> idsArray) {
        if(idsArray != null && idsArray.size() > 0){
            for(int i=0;i<idsArray.size();i++){
                this.deleteById(idsArray.get(i));
            }
        }
    }

    public Worker selectConsultantByOrgIdRandomly() {
        List<Worker> workerList=workerMapper.selectListByRid(ConstantRole.ROLE_NURSERY_CONSULTANT);
        Collections.shuffle(workerList);
        if(workerList.size()>0){
            return workerList.get(0);
        }else{
            return null;
        }
    }
    public List<Worker> selectFollowerList(Long orgId) {
        return workerMapper.selectFollowerList(orgId);
    }

}
